<template>
    <view class="flex flex-row flex-row-center-start">
        <TmCheckbox :followTheme="props.followTheme" closeAni v-if="showCheckbox" :color="nodeData['color']" :indeterminate="_indeterminate"  @change="checkboxChange" :disabled="nodeData['disabled']" v-model="_checked"  :value="nodeData[props.fieldNames.id]"></TmCheckbox>
    </view>
</template>
<script lang="ts" setup>
import TmCheckbox from '../tm-checkbox/tm-checkbox.vue';
import {ref,getCurrentInstance, inject, computed, toRaw, watch, watchEffect,Ref} from "vue"
import { baseNodeData } from "./interface";
import { treeFlat,queryParentNode } from './util';
const {proxy} = getCurrentInstance();
const props = defineProps({
	followTheme: {
		type: [Boolean,String],
		default: true
	},
    /**
     * 数据
    * @description 生成树结构的数据。结构必须要有id字段。当然可以通过field-names来映射，如果你的唯一标识字段不是Id的话。
    */
    data: {
        type: Object,
        default: () => {},
        required: true
    },
     /**
     * 数据结构字段的映射表。
     */
    fieldNames:{
        type:Object,
        default:()=>{
            return {
                id:'id',
                text:'text'
            }
        }
    },
})
//父级方法。
let parent = proxy.$parent
while (parent) {
    if(parent?.TreeParaentName=='tmTree'||!parent){
        break;
    }else{
        parent = parent?.$parent??undefined
    }
}
const TreeParentIds = inject("TreeParentIds",ref([]))
const TreePareantSelectedIds = inject("TreePareantSelectedIds",ref([]))
const color = parent?.$props.color??'primary';
const nodeData= computed(()=><baseNodeData>{
        icon:props.data['icon']??'',//节点图标。
        color:props.data['color']||color,//节点颜色主题
        disabled:props.data['disabled']??false,//节点是否禁用
        text:props.data[props.fieldNames.text],//节点标题
        id:props.data[props.fieldNames.id],//节点标识
    })
const allListFlat = parent.getAllListData();

const showCheckbox = inject("TreeNodeCheckable",computed(()=>true))
//当前是否选中Id;
const _checked:Ref<string|number> = ref('')
//当前是否半选中状态。
const _indeterminate = ref(false)
//是否允许多选。
const _multiple = parent.$props.multiple??true;
//本节点子节点所有节点，含 父和子
const flatlist = computed(()=>treeFlat(props.data['children']??[],props.fieldNames.id));
//所有数据父节点
let listParentFlat = queryParentNode(allListFlat,props.fieldNames.id);
let _listParentFlat = new Set(listParentFlat)
//本节点下所有子节点 ，不包含父节点
const childreNodelist = flatlist.value.filter(el=>!_listParentFlat.has(el))
//本节点下的呢父节点，不包含子
const parentNodelist = flatlist.value.filter(el=>_listParentFlat.has(el))

//初始时，是否有本节点。有本节点就需要 你全选下面的子节点。
let sletctedIdArray = TreeParentIds.value.filter((el:string|number)=>el==nodeData.value.id);
if(flatlist.value.length>0&&sletctedIdArray.length>0){
    if(_multiple){
        parent?.onSelected(childreNodelist)
        parent?.onSelectedParent(parentNodelist)
    }
}
    
// function setChecked(){
//     setExpaned
// }
// watchEffect(()=>setExpaned())

function checkboxChange(e:boolean){
    if(!_multiple&&TreePareantSelectedIds.value.length>=1){
         parent?.checkAll(false);
    }
     if(e){
        // parent?.onSelectedParent([nodeData.value.id,...flatlist.value])
        parent?.onSelectedParent([nodeData.value.id,...parentNodelist])
        parent?.onSelected(childreNodelist)
        // console.log(childreNodelist)
    }else{
        // parent?.onUnSelectedParent([nodeData.value.id,...flatlist.value])
        parent?.onUnSelectedParent([nodeData.value.id,...parentNodelist])
        parent?.onUnSelected(childreNodelist)
    }
    //父节点被点击。
	parent?.onCheck({checked:e,data:toRaw(props.data)})
}




    // console.log(TreePareantSelectedIds.value)
    // console.log(TreePareantSelectedIds.value.filter(el=>el!=nodeData.value.id))
    const ids = toRaw(nodeData.value.id);
function setExpaned(){
    //计算它的子集是否全部被选中了。
    //如果差集长度大于0表示没有全部选中。
    //排除本身 。
    let ar:Set<string|number> = new Set([...TreePareantSelectedIds.value,...TreeParentIds.value]);
    let _seleteds = flatlist.value.filter((el:string|number)=>ar.has(el))
    // console.log(ids,_seleteds.length)
    // console.log(_seleteds.length)
    if(_seleteds.length == flatlist.value.length){
        //全部选中后，把父级设置选中状态，否则为半选。
        _indeterminate.value = false;
        _checked.value = nodeData.value.id;
        // parent?.onSelectedParent([nodeData.value.id])
        return;
    }
    if(_seleteds.length>0){
        _indeterminate.value = true;
        _checked.value = ''
        //  parent?.onUnSelectedParent([nodeData.value.id])
        return;
    }
    if(_seleteds.length==0){
		_indeterminate.value = false;
		_checked.value = ''
        // parent?.onUnSelectedParent([nodeData.value.id])
    }
}
watchEffect(()=>setExpaned())

function setExpanedParent(){
    //计算它的子集是否全部被选中了。
    //如果差集长度大于0表示没有全部选中。
    let ar:Set<string|number> = new Set(TreeParentIds.value);
    let _seleteds = flatlist.value.filter((el:string|number)=>ar.has(el))
    if(_seleteds.length == flatlist.value.length){
        //全部选中后，把父级设置选中状态，否则为半选。
        _indeterminate.value = false;
        _checked.value = nodeData.value.id;
        // parent?.onSelected([nodeData.value.id])
        return;
    }
    if(_seleteds.length>0){
        _indeterminate.value = true;
        _checked.value = ''
        //  parent?.onUnSelected([nodeData.value.id])
        return;
    }
    if(_seleteds.length==0){
		_indeterminate.value = false;
		_checked.value = ''
        // parent?.onUnSelected([nodeData.value.id])
    }
}
// watchEffect(()=>setExpanedParent())

watch(()=>_checked.value,(newval,oldval)=>{
    let ar:Set<string|number> = new Set([...TreePareantSelectedIds.value,...TreeParentIds.value]);
    let _seleteds = flatlist.value.filter((el:string|number)=>ar.has(el))
    if(_seleteds.length == flatlist.value.length){
        parent?.onSelectedParent([nodeData.value.id])
        return;
    }
    if(_seleteds.length>0){
       parent?.onUnSelectedParent([nodeData.value.id])
       return;
    }
    if(_seleteds.length==0){
        parent?.onUnSelectedParent([nodeData.value.id])
    }
})

</script>